/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.muni.fi.pa165.mushroom.website.client.web;

import cz.muni.fi.pa165.mushroom.website.client.dto.ForestDto;
import cz.muni.fi.pa165.mushroom.website.client.dto.MushroomDto;
import cz.muni.fi.pa165.mushroom.website.client.validator.ForestValidator;
import cz.muni.fi.pa165.mushroom.website.client.validator.MushroomValidator;
import java.io.IOException;
import java.util.List;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.ModelAndView;

/**
 *
 * @author roman
 */
@Controller
@RequestMapping("/mushroom")
public class MushroomClientController {
     private String remoteHost = "http://localhost:8080/pa165/rest/mushroom/";
    
    @Autowired
    private RestTemplate rest;
    
    private MushroomDto addedMushroomBackingBean;
    private MushroomDto editedMushroomBackingBean;
    
    @Autowired
    @Qualifier("mushroomValidator")
    private MushroomValidator mushroomValidator;

    @PostConstruct
    public void init() {
        addedMushroomBackingBean = new MushroomDto();
    }

    @RequestMapping(method = RequestMethod.GET)
    public ModelAndView renderList() {
        String url = remoteHost + "listMushrooms";
        List<MushroomDto> list = rest.getForObject(url,List.class);
        ModelAndView mav = new ModelAndView();
        mav.addObject("mushrooms", list);
        mav.setViewName("mushroom/list");
        return mav;
    }

    @RequestMapping(value = "/listByType/{type}", method = RequestMethod.GET)
    public ModelAndView renderListByType(@PathVariable String type) {
        String url = remoteHost + "getMushroomsType/" + type;
        List<MushroomDto> list = rest.getForObject(url,List.class);
        ModelAndView mav = new ModelAndView();
        mav.addObject("mushrooms", list);
        mav.setViewName("mushroom/list");
        return mav;
    }   
    
    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public ModelAndView renderDetail(@PathVariable String id) {
        String url = remoteHost + "getMushroom/" + id;
        ModelAndView mav = new ModelAndView();
        mav.addObject("mushroom", getRemoteMushroom(id));
        mav.setViewName("mushroom/detail");
        return mav;
    }

    @RequestMapping(value = "/add", method = RequestMethod.GET)
    public ModelAndView renderAdd() {
        ModelAndView mav = new ModelAndView();
        mav.addObject("addedMushroom", addedMushroomBackingBean);
        mav.setViewName("mushroom/add");
        return mav;
    }

    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public String addMushroom(@ModelAttribute("addedMushroom") MushroomDto mushroomDto,
            BindingResult result, ModelMap modelMap) {
        mushroomValidator.validate(mushroomDto, result);
        String url = remoteHost + "createMushroom/";
        if (result.hasErrors()) {
            addedMushroomBackingBean = mushroomDto;
            modelMap.put(BindingResult.class.getName() + "addedMushroom", result);
            return "mushroom/add";
        } else {
            rest.postForObject(url, mushroomDto, MushroomDto.class);
            return "redirect:/mushroom/add/success";
        }
    }

    @RequestMapping(value = "/add/success", method = RequestMethod.GET)
    public ModelAndView addSuccess() {
        ModelAndView mav = new ModelAndView();
        mav.addObject("successMessage", "mushroom.add.success");
        mav.setViewName("mushroom/success");
        return mav;
    }

    @RequestMapping(value = "/edit/{id}", method = RequestMethod.GET)
    public ModelAndView renderEdit(@PathVariable String id) {
        ModelAndView mav = new ModelAndView();
        editedMushroomBackingBean = getRemoteMushroom(id);
        mav.addObject("editedMushroom", editedMushroomBackingBean);
        mav.setViewName("mushroom/edit");
        return mav;
    }

    @RequestMapping(value = "/edit/{id}", method = RequestMethod.POST)
    public String editMushroom(@ModelAttribute("editedMushroom") MushroomDto editedMushroom,
            @PathVariable String id, BindingResult result, ModelMap modelMap) {
        mushroomValidator.validate(editedMushroom, result);
        String url = remoteHost + "editMushroom";
        if (result.hasErrors()) {
            modelMap.put("editedMushroom", editedMushroom);
            modelMap.put(BindingResult.class.getName() + "editedMushroom", result);
            return "mushroom/edit";
        } else {
            rest.put(url, editedMushroom);
            return "redirect:/mushroom/edit/success";
        }
    }

    @RequestMapping(value = "/edit/success", method = RequestMethod.GET)
    public ModelAndView editSuccess() {
        ModelAndView mav = new ModelAndView();
        mav.addObject("successMessage", "mushroom.edit.success");
        mav.setViewName("mushroom/success");
        return mav;
    }

    @RequestMapping(value = "/delete/{id}", method = RequestMethod.GET)
    public ModelAndView renderDelete(@PathVariable String id) {
        ModelAndView mav = new ModelAndView();
        MushroomDto deletedMushroom = getRemoteMushroom(id);
        mav.addObject("deletedMushroom", deletedMushroom);
        mav.setViewName("mushroom/delete");
        return mav;
    }

    @RequestMapping(value = "/delete/{id}", method = RequestMethod.POST)
    public String deleteMushroom(@PathVariable String id) {
        String url = remoteHost + "deleteMushroom/" + id;
        rest.delete(url);
        return "redirect:/mushroom/delete/success";
    }

    @RequestMapping(value = "/delete/success", method = RequestMethod.GET)
    public ModelAndView deleteSuccess() {
        ModelAndView mav = new ModelAndView();
        mav.addObject("successMessage", "mushroom.delete.success");
        mav.setViewName("mushroom/success");
        return mav;
    }

    @ExceptionHandler(RestClientException.class)
    public ModelAndView badFormat(RestClientException ex) {
        ModelAndView mav = new ModelAndView();
        mav.addObject("error", "Remote host " + remoteHost + " returned error code:");
        if (ex.contains(IOException.class)) {
            mav.addObject("code", "503 Service Unavailable");
        } else {
            mav.addObject("code", ex.getMessage());
            //mav.addObject("code", ex.getRootCause().getMessage());
        }
        mav.setViewName("mushroom/error");

        return mav;
    }

    private MushroomDto getRemoteMushroom(String id) throws RestClientException {
        String url = remoteHost + "getMushroom/" + id;
        MushroomDto resp = rest.getForObject(url, MushroomDto.class);       
        
        return resp;
    }
}
